package newsEditor;

import static utils.NewsEventSystemUtils.getDomainByNews;
import static utils.NewsEventSystemUtils.getDomains;
import static utils.NewsEventSystemUtils.getNewsByTitle;

import reader.AckEvent;
import newsEventSystem.Console;
import newsEventSystem.Domain;
import newsEventSystem.News;
import newsEventSystem.NewsCenter;
import event.Event;
import event.EventService;
import event.InvalidEventTypeException;
import event.Publisher;
import event.Subscriber;

public class NewsEditor extends Thread implements Publisher, Subscriber {

	private NewsCenter newsCenter = NewsCenter.getInsance();
	private EventService eventService = EventService.getInstance();
	private Console console = new Console("NewsEditor");

	private static String getMenuText() {
		String menuText = "1.Add news\n" + "2.Modify news\n"
				+ "3.Remove news\n" + "4.Add subtopic\n"
				+ "5.Subscribe for acknowledgement\n" + "6.Exit\n";
		return menuText;
	}

	public void run() {
		console.writeLine(getMenuText());
		int option = 0;
		String[] splitLine;
		String input, title, body, source;
		News news;
		Domain temp = null;
		do {
			console.writeLine("Please insert your option:");
			try {
				String line = console.readLine();
				if (line == null) {
					option = 6;
				} else {
					option = Integer.parseInt(line.trim());
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			switch (option) {
			case 1:
				console.writeLine(getDomains());
				console.writeLine("Please choose the domain:");
				input = console.readLine();
				for (Domain d : newsCenter.getDomains())
					if (d.getDomainName().equals(input))
						temp = d;
				if (temp == null) {
					console.writeLine("Please insert a valid domain for the news!");
					break;
				}
				console.writeLine("Please insert title of the news : ");
				title = console.readLine().trim();
				console.writeLine("Please insert body of the news : ");
				body = console.readLine().trim();
				console.writeLine("Please insert source of the news : ");
				source = console.readLine().trim();
				news = new News(console.getAuthorName(), source, temp, title,
						body);
				temp.addNewsToDomain(news);
				AddedNewsEvent aNews = new AddedNewsEvent(news, this);
				eventService.publish(aNews);
				break;
			case 2:
				console.writeLine("Please insert title of the news to be modified : ");
				title = console.readLine().trim();
				news = getNewsByTitle(title);
				if (news == null) {
					console.writeLine("There is no such news!");
					break;
				} else {
					if (news.getNewsAuthor().equals(console.getAuthorName())) {
						console.writeLine("Please insert new body for the news:");
						body = console.readLine().trim();
						news.setBody(body);
						news.setModifiedDate();
						console.writeLine("Article has been modified");
						ModifiedNewsEvent mNews = new ModifiedNewsEvent(news,
								this);
						eventService.publish(mNews);
					} else {
						console.writeLine("This is not your article!");
					}
				}
				break;
			case 3:
				console.writeLine("Please insert title of the news to be deleted : ");
				title = console.readLine().trim();
				news = getNewsByTitle(title);
				if (news == null) {
					console.writeLine("Please insert the title of an existing article!");
					break;
				} else {
					if (news.getNewsAuthor().equals(console.getAuthorName())) {
						System.out.println(news.getNewsAuthor());
						temp = getDomainByNews(news);
						temp.removeNews(news);
						console.writeLine("Article has been removed.");
						DeletedNewsEvent dNews = new DeletedNewsEvent(news,
								this);
						eventService.publish(dNews);
					} else {
						console.writeLine("This is not your article!");
					}
				}
				break;
			case 4:
				console.writeLine("<subdomain name> <parent domain>");
				splitLine = console.readLine().split(" ");
				String subdomainName = splitLine[0];
				String parentDomain = splitLine[1];
				Domain parent = null;
				boolean exists = false;
				for (Domain d : newsCenter.getDomains())
					if (d.getDomainName().equals(parentDomain)) {
						exists = true;
						parent = d;
					}
				if (!exists) {
					console.writeLine("The parent domain does not exist!");
					break;
				} else {
					temp = new Domain(subdomainName, parent);
					newsCenter.addDomain(temp);
					AddedSubtopicEvent aDomain = new AddedSubtopicEvent(this);
					eventService.publish(aDomain);
				}
				break;
			case 5:
				try {
					eventService.subscribe(AckEvent.class, new AckFilter(console.getAuthorName()),
							this);
				} catch (InvalidEventTypeException e) {
					e.printStackTrace();
				}
				break;
			}
		} while (option != 6);
		console.close();
	}

	@Override
	public void inform(Event event) {
		if (event instanceof AckEvent) {
			console.writeLine(((AckEvent) event).getMessage());
		}
	}
}
